package cn.edu.nsmc.modules.sys.controller;

import java.text.ParseException;
import java.util.*;

import cn.edu.nsmc.common.utils.ShiroUtils;
import cn.edu.nsmc.common.utils.WorkSheetTypeEnum;
import cn.edu.nsmc.modules.sys.dao.SysUserDao;
import cn.edu.nsmc.modules.sys.entity.SysUserEntity;
import cn.edu.nsmc.modules.sys.entity.SysWorksheetRepairEntity;
import cn.edu.nsmc.modules.sys.entity.form.ListData;
import cn.edu.nsmc.modules.sys.form.req.ReqFeeBackWorksheetBody;
import cn.edu.nsmc.modules.sys.form.req.ReqWorkSheetListBody;
import cn.edu.nsmc.modules.sys.service.SysWorksheetRepairService;
import org.apache.commons.lang.BooleanUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import cn.edu.nsmc.common.utils.PageUtils;
import cn.edu.nsmc.common.utils.R;
import cn.edu.nsmc.modules.sys.entity.SysWorksheetAuditNode;
import cn.edu.nsmc.modules.sys.entity.SysWorksheetRecord;
import cn.edu.nsmc.modules.sys.form.req.ReqAssignWorksheetBody;
import cn.edu.nsmc.modules.sys.service.SysWorksheetAuditNodeService;
import cn.edu.nsmc.modules.sys.service.SysWorksheetRecordService;

import javax.servlet.http.HttpServletResponse;

/**
 * 工单记录管理
 * 备注信息 作者:moon 日期:2024/11/26 more
 * @module 网络管家
 */
@RestController
@RequestMapping("sys/worksheetRecord")
public class SysWorksheetRecordController {
    @Autowired
    private SysWorksheetRecordService sysWorksheetRecordService;
    @Autowired
    private SysWorksheetAuditNodeService sysWorksheetAuditNodeService;
    @Autowired
    private SysWorksheetRepairService sysWorksheetRepairService;
    @Autowired
    private SysUserDao sysUserDao;

    Logger logger = org.slf4j.LoggerFactory.getLogger(getClass());

    /**
     * 分页查询工单
     *
     * @param pageParams 分页参数，放在 url 传递传参
     * @param listBody   查询条件，放请求 payload 传参
     */
    @RequestMapping("/list")
    public R list(@RequestParam Map<String, Object> pageParams, @RequestBody(required = false) ReqWorkSheetListBody listBody) {
        PageUtils page;
        if (listBody != null) {
            page = sysWorksheetRecordService.queryPage(pageParams, listBody);
        } else {
            page = sysWorksheetRecordService.queryPage(pageParams);
        }
        return R.ok().put("page", page);
    }
    /**
     * 筛选工单列表并导出为Excel
     * 通过 审核状态、工单类型、维修人员、审核人员、工单开始/结束时间 筛选工单列表并导出为Excel
     * @return 响应描述
     */
    @PostMapping("/export")
    public void export(@RequestBody ReqWorkSheetListBody listBody, HttpServletResponse response) {
        //System.out.println(11);
        sysWorksheetRecordService.export(listBody,response);
    }
//    @GetMapping("/export")
//    public void export( HttpServletResponse response) {
//        sysWorksheetRecordService.export(new ReqWorkSheetListBody(),response);
//    }


    @GetMapping("/wx/list/{userId}")
    public R wxList(@PathVariable("userId") Long userId) {
        Map<Integer, List<SysWorksheetRecord>> list = sysWorksheetRecordService.wxList(userId);

        return R.ok().put("data", list);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") Long id) {
        SysWorksheetRecord sysWorksheetRecord = sysWorksheetRecordService.getById(id);

        return R.ok().put("sysWorksheetRecord", sysWorksheetRecord);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    public R save(@RequestBody SysWorksheetRecord sysWorksheetRecord) {
        if (sysWorksheetRecord.getApplicantId() == null || sysWorksheetRecord.getWorksheetType() == null)
            return R.error();
        // 初始化新工单
        sysWorksheetRecord.setAuditStatus(0);
        // 默认让管理员处理
        sysWorksheetRecord.setAuditorId(1);
        Date now = new Date();
        sysWorksheetRecord.setApplyTime(now);
        sysWorksheetRecord.setStartTime(now);
        sysWorksheetRecord.setPriority(1);

        sysWorksheetRecordService.save(sysWorksheetRecord);

        // 维修工单需要生成维修记录
        if(Objects.equals(WorkSheetTypeEnum.MAINTENANCE_WORK_ORDER.getValue(), sysWorksheetRecord.getWorksheetTypePid())){
            SysWorksheetRepairEntity repairEntity = sysWorksheetRecord.getRepairEntity();
            repairEntity.setWorksheetRecordId(sysWorksheetRecord.getId());
            sysWorksheetRepairService.save(repairEntity);
        }
        // 初始化节点信息
        SysWorksheetAuditNode sysWorksheetAuditNode = new SysWorksheetAuditNode();
        sysWorksheetAuditNode.setWorksheetId(sysWorksheetRecord.getId())
                .setAuditor(Long.valueOf(sysWorksheetRecord.getAuditorId()))
                .setAuditResult("已上传申请").setAuditTime(new Date());

        sysWorksheetAuditNodeService.save(sysWorksheetAuditNode);

        return R.ok("业务已提交");
    }

    /**
     * 更新工单 // TODO 等待实现
     */
    @RequestMapping("/update")
    @RequiresPermissions("sys:sysworksheetrecord:update")
    public R update(@RequestBody SysWorksheetRecord sysWorksheetRecord) {
        // sysWorksheetRecordService.updateById(sysWorksheetRecord);

        return R.ok();
    }

    /**
     * 为工单指派维修人员
     */
    @RequestMapping("/assign")
    public R assign(@RequestBody ReqAssignWorksheetBody sysWorksheetRecord) {
        try {
            String resultStr = sysWorksheetRecordService.assignWorksheet(sysWorksheetRecord);
            return R.ok(resultStr);
        } catch (IllegalArgumentException ex) {
            logger.error(ex.getMessage());
            return R.error(ex.getMessage());
        }
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    @RequiresPermissions("sys:sysworksheetrecord:delete")
    public R delete(@RequestBody Long[] ids) {
        sysWorksheetRecordService.removeByIds(Arrays.asList(ids));

        return R.ok();
    }

    @RequestMapping("/feedbackWorksheet")
    public R feedbackWorksheet(@RequestBody ReqFeeBackWorksheetBody feedBackWorksheetBody) {
        try {
            String resultStr = null;
            if (BooleanUtils.toBoolean(feedBackWorksheetBody.getIsReject())) {
                resultStr = sysWorksheetRecordService.rejectWorksheet(feedBackWorksheetBody);
            } else {
                resultStr = sysWorksheetRecordService.feedbackWorksheet(feedBackWorksheetBody);

            }
            return R.ok(resultStr);
        } catch (IllegalArgumentException | IllegalStateException ex) {
            logger.error(ex.getMessage());
            return R.error(ex.getMessage());
        }
    }

    /**
     * 根据工单 id 查询 该工单的所有节点，并按时间从远到近排序
     *
     * @param worksheetId 工单 id
     * @return 该工单的所有节点
     */
    @RequestMapping("/auditNode/{worksheetId}")
    public R auditNode(@PathVariable("worksheetId") Long worksheetId) {
        List<SysWorksheetAuditNode> list = sysWorksheetAuditNodeService.queryByWorksheetId(worksheetId);

        return R.ok().put("data", list);
    }

    //多条件查询、分类查询
    @PostMapping("getList")
    public R getList(@RequestBody SysWorksheetRecord sysWorksheetRecord, Integer page, Integer size) {
        return sysWorksheetRecordService.getList(sysWorksheetRecord, (page - 1) * size, size);
    }

    //备注工单（管理端无新增、是否修改？）
    @PutMapping("commentWorksheet")
    public R commentWorksheet(Long id, String note) {
        return sysWorksheetRecordService.commentWorksheet(id, note);
    }

    //批量拒绝、允许工单
    @PutMapping("auditWorksheet")
    public R auditWorksheet(@RequestBody ListData ld, Integer auditType, String cause) {
        return sysWorksheetRecordService.auditWorksheet(ld.getIds(), auditType, cause);
    }

    @GetMapping("getInformation")
    public R getInformation() throws ParseException {
        return sysWorksheetAuditNodeService.getInformation();
    }

    // TODO: 2024/5/29 数据可视化，首页做的好看一点（首页查看数据按周，月，年统计）；模板管理测试和完善；导入导出excel文件；推送管理
    // TODO: 2024/5/29 管理员手动新增工单记录，注意工单的状态处理，现在，只需要新增一个新的工单即可（并可指定维修人员）
    //notes:因为有时候需要处理电话报修，由管理员手动添加一条
    @PostMapping("/addRecordByAdmin")
    public R addRecordByAdmin(@RequestBody SysWorksheetRecord sysWorksheetRecord) {
        //还有维修人员的信息，方案二：直接让前端调用小程序的接口
        //这里采用方案一，管理员一套实现，并直接在Controller实现了
        //填写工单基本信息
        if (sysWorksheetRecord.getWorksheetType() == null) return R.error();
        if (sysWorksheetRecord.getApplicantId() == null)
            sysWorksheetRecord.setApplicantId(sysWorksheetRecord.getAuditorId());
        // 初始化新工单
        if (sysWorksheetRecord.getRepairmanId() != null) {
            sysWorksheetRecord.setAuditStatus(3);//默认管理员已通过
        } else {
            sysWorksheetRecord.setAuditStatus(1);//默认管理员已通过
        }
        // 默认让管理员处理
        Date now = new Date(System.currentTimeMillis());
        sysWorksheetRecord.setApplyTime(now);
        sysWorksheetRecord.setStartTime(now);
        sysWorksheetRecord.setPriority(1);
        sysWorksheetRecord.setMemo("这是管理员手动添加的业务记录");
        sysWorksheetRecordService.save(sysWorksheetRecord);

        //生成申请人信息
        SysWorksheetRepairEntity repairEntity = sysWorksheetRecord.getRepairEntity();
        if (repairEntity == null) {
            repairEntity = new SysWorksheetRepairEntity();
        }
        repairEntity.setWorksheetRecordId(sysWorksheetRecord.getId());
        if (sysWorksheetRecord.getApplicantId().equals(sysWorksheetRecord.getAuditorId())) {
            //设为管理员
            SysUserEntity repairAdmin = sysUserDao.getOneById(sysWorksheetRecord.getAuditorId());
            repairEntity.setUserType(repairAdmin.getType());
            repairEntity.setUserName(repairAdmin.getUsername());
            repairEntity.setUserNo(repairAdmin.getPersonalNumber());
            repairEntity.setUserId(sysWorksheetRecord.getAuditorId());
            repairEntity.setDepartment(repairAdmin.getDepartmentName());
        }
        sysWorksheetRepairService.save(repairEntity);
        //生成节点信息
        SysWorksheetAuditNode sysWorksheetAuditNode = new SysWorksheetAuditNode();
        sysWorksheetAuditNode.setWorksheetId(sysWorksheetRecord.getId())
                .setAuditor(Long.valueOf(sysWorksheetRecord.getAuditorId()))
                .setAuditResult("已由管理员填写业务").setAuditTime(now);
        if (sysWorksheetRecord.getRepairmanId() != null) {
            sysWorksheetAuditNode.setAuditResult("已由管理员填写业务,并指派维修人员" + sysUserDao.getNameById(sysWorksheetRecord.getRepairmanId()));
        }
        sysWorksheetAuditNodeService.save(sysWorksheetAuditNode);


        return R.ok("新增业务记录成功");
    }

}
